home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Programmer Disk
/
The Programmer Disk (Microforum).iso
/
xpro
/
c2
/
pro24
/
ega.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-04-17
|
5KB
|
242 lines
/* EGA - routines to drive the EGA board.
*/
#include "lib.h"
#include "vgr.h"
/* proto's
*/
int ega_init();
int ega_select_plane();
int ega_write_row();
int ega_clear();
int ega_set_palette();
int ega_clr_point();
int ega_xor_point();
int ega_get_point();
int ega_set_point();
int ega_mode();
int ega_null();
int movmem();
int peekb();
int pokeb();
int vgr_mode();
static int (*ega_func[])() = {
ega_init, ega_clear, ega_set_point, ega_clr_point,
ega_xor_point, ega_get_point, ega_write_row, ega_select_plane,
ega_set_palette,ega_mode, movmem, peekb, pokeb,
ega_null, ega_null };
/* EGA stuff
*/
#define REG_ADDRESS 0x3c4
#define REG_MAPMASK 0x3c5
#define REG_IDX 0x3ce
#define REG_VAL 0x3cf
#define OUTIDX(i,v) {outportb(REG_IDX,i);outportb(REG_VAL,v);}
static unsigned char far * far *ega_column;
static int ega_null()
{
return ERROR;
}
int ega_init()
{
void *malloc();
int row;
if ( !ega_column )
ega_column = CASTUCFPP malloc( sizeof CASTUCFP * 350 );
if ( !ega_column )
return ERROR;
for ( row = 0; row < 350; row++ )
ega_column[row] = CASTUCFP BASE_EGA + row*80l;
VGR_HRES = 640;
VGR_VRES = 350;
VGR_NBPL = 80;
VGR_NCOLORS = 16;
movmem( ega_func, vgr_func, sizeof(vgr_func) );
return OK;
}
int ega_select_plane( plane )
int plane;
{
outportb( REG_ADDRESS, 2 );
outportb( REG_MAPMASK, plane >= 0 ? 1 << (plane & 0x03) : -plane );
}
/* A version for the CGA card will have to check for retrace
before copying each byte.
*/
int ega_write_row( row, prow, nbytes )
register unsigned int nbytes;
unsigned char *prow;
int row;
{
movmem( prow, ega_column[row], nbytes );
}
int ega_clear()
{
ega_select_plane( -0x0f );
setmem( BASE_EGA, 0x8000, 0 );
ega_select_plane( 0 );
}
int ega_set_palette( reg, red, green, blue )
unsigned char reg, red, green, blue;
{
REGS r;
unsigned char v;
v = (blue & 0x01) | (blue & 0x02) * 4
| (green & 0x01) * 2 | (green & 0x02) * 8
| (red & 0x01) * 4 | (red & 0x02) * 16;
r.ax = 0x1000;
r.bx = ((unsigned int)v << 8) | reg;
sysint( 0x10, &r, &r );
}
int ega_clr_point( x, y )
unsigned int x, y;
{
ega_set_point( x, y, 0 );
}
int ega_xor_point( x, y, color )
unsigned int x, y, color;
{
ega_set_point( x, y, ega_get_point( x, y ) ^ color );
}
int ega_get_point( x, y )
unsigned int x, y;
{
#if 1
REGS r;
r.ax = 0x0d00;
r.dx = y;
r.cx = x;
sysint( 0x10, &r, &r );
return r.ax & 0xff;
#endif
#if 0
unsigned char plane, mask, b, color;
unsigned char far *p;
p = ega_column[y] + (x>>3);
b = 0x80 >> (x & 0x07);
outportb( REG_ADDRESS, 2 );
for ( color=plane=0; plane < 4; plane++ )
{ outportb( REG_MAPMASK, mask = (1 << plane) );
color |= !!(*p & b) * mask;
};
return color;
#endif
}
int ega_set_point( x, y, color )
unsigned int x, y, color;
{
#if 1
/* this works, but is painfully slow!! */
REGS r;
r.ax = 0x0c00 | color;
r.dx = y;
r.cx = x;
sysint( 0x10, &r, &r );
return OK;
#endif
#if 0
/* This is my routine. It works if you stick to the color white!
otherwise, it doesn't work because it's apparently not possible
to directly read the EGA VRAM.
*/
unsigned char plane, mask, b;
unsigned char far *p;
p = ega_column[y] + (x>>3);
b = (unsigned int)0x80 >> (x & 0x07);
outportb( REG_ADDRESS, 2 );
for ( plane=0; plane < 4; plane++ )
{ outportb( REG_MAPMASK, mask = ((unsigned int)1 << plane) );
if ( color & mask )
*p |= b;
else *p &= ~b;
};
#endif
#if 0
/* This is Gary Entsmingers routine,
which works like an XOR function instead of
a set function. I don't have the foggiest
notion how it works. There's no reference in
any of the (incomplete) doc that I've got
to the registers used here.
*/
unsigned char b;
unsigned char far *p;
p = ega_column[y] + (x>>3);
b = (unsigned int)0x80 >> (x & 0x07);
OUTIDX(0,color);
OUTIDX(1, 0x0f);
OUTIDX(8, b);
OUTIDX(3, 0x18);
/* It doesn't seem to matter what you do here as long as you
don't assign -1 to *p. *p |= -1, *p &= -1, *p ^= *p and *p = *p
all have the same effect - a hardware XOR function!
*/
*p &= 0xff;
OUTIDX(0,0);
OUTIDX(1,0);
OUTIDX(8,0xff);
OUTIDX(3,0);
#endif
}
int ega_mode( mode )
int mode;
{
if ( mode == MODE_APA0 )
return vgr_mode( 16 );
if ( mode == MODE_TEXT0 )
return vgr_mode( 3 );
return ERROR; /* mode not currently supported */
}